package com.ruoyi.auth.service;

import cn.hutool.core.lang.TypeReference;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.github.shepherdviolet.glacimon.java.conversion.ByteUtils;
import com.github.shepherdviolet.glacimon.java.crypto.SM2Cipher;
import com.github.shepherdviolet.glacimon.java.crypto.SM2KeyGenerator;
import com.github.shepherdviolet.glacimon.java.crypto.base.CommonCryptoException;
import com.ruoyi.auth.AuthenticationConfigurationProvider;
import com.ruoyi.auth.UnifiedAuthenticationSettings;
import com.ruoyi.auth.constant.UnifiedAuthenticationConstants;
import com.ruoyi.auth.data.*;
import io.micrometer.common.util.StringUtils;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

/**
 * 访问统一认证接口的服务
 * email：954219492@qq.com
 * 2025-03-07
 */
//@Service
//@RequiredArgsConstructor
public class UnifiedAuthenticationService {

    private static final Logger log = LoggerFactory.getLogger(UnifiedAuthenticationService.class);
    private final AuthenticationConfigurationProvider settingsProvider;
    private final UnifiedAuthenticationSettings settings;

    public UnifiedAuthenticationService(
        AuthenticationConfigurationProvider configurationProvider
    ) {
        this.settingsProvider = configurationProvider;
        this.settings = settingsProvider.getUnifiedAuthenticationSettings();
    }

    /**
     * 使用票据获取令牌
     * @param ticket
     * @return
     */
    public TokenData exchangeTicketForToken(String ticket) {
        // 实现与第三方平台交互的逻辑
//        Map<String, String> content = new HashMap<>(1);
//        content.put("ticket", ticket);
//        BizContentParameter data = new BizContentParameter(this.settings.getApplicationId(), content);
//
//        Map<String, Object> parameters = buildRequestParameters(this.settings, UnifiedAuthenticationConstants.ServiceName.retrieveToken, data);
//
//        String responseBodyString = HttpUtil.post(this.settings.getBaseUrl() + this.settings.getExchangeTokenPath(),
//                parameters, UnifiedAuthenticationConstants.TIMEOUT);
//        // 解析JSON字符串为JSONObject
//        JSONObject jsonObject = JSONUtil.parseObj(responseBodyString);
//        // 获取"data"字段的字符串值
//        String cipherText = jsonObject.getStr("data");
//        String tokenJson = descrypt(cipherText, this.settings.getPrivateKey());
        String tokenJson = getDataJson(UnifiedAuthenticationConstants.ContentKey.ticket, ticket);
        ResponseData<TokenData> responseData = JSONUtil.toBean(tokenJson,
                new TypeReference<ResponseData<TokenData>>() {}, false);
        return responseData.getData();
    }

    /**
     * 根据令牌获取自然人用户详细信息
     * @param token
     * @return
     */
    public NaturalUserData retrieveNaturalUser(String token) {
        String tokenJson = getDataJson(UnifiedAuthenticationConstants.ContentKey.token, token);
        ResponseData<NaturalUserData> responseData = JSONUtil.toBean(tokenJson,
                new TypeReference<ResponseData<NaturalUserData>>() {}, false);
        return responseData.getData();
    }

    /**
     * 根据令牌获取法人用户详细信息
     * @param token
     * @return
     */
    public LegalUserData retrieveLegalUser(String token) {
        String tokenJson = getDataJson(UnifiedAuthenticationConstants.ContentKey.token, token);
        ResponseData<LegalUserData> responseData = JSONUtil.toBean(tokenJson,
                new TypeReference<ResponseData<LegalUserData>>() {}, false);
        return responseData.getData();
    }

    private Map<String, Object> buildRequestParameters(UnifiedAuthenticationSettings settings,
           String interfaceName,
           BizContentParameter bizContentParameter
           ) {
        Map<String, Object> parameters = new HashMap<>(8);
        parameters.put(UnifiedAuthenticationConstants.ParameterName.appId, settings.getApplicationId());
        parameters.put(UnifiedAuthenticationConstants.ParameterName.interfaceId, interfaceName);
        parameters.put(UnifiedAuthenticationConstants.ParameterName.version, settings.getVersion());
        parameters.put(UnifiedAuthenticationConstants.ParameterName.bizContent, bizContentParameter.toString());
        parameters.put(UnifiedAuthenticationConstants.ParameterName.charset, settings.getCharset());
        parameters.put(UnifiedAuthenticationConstants.ParameterName.timestamp, String.valueOf(System.currentTimeMillis()));
        parameters.put(UnifiedAuthenticationConstants.ParameterName.origin, UnifiedAuthenticationConstants.ORIGIN_PC);
        // 以上是 7 个参数
        parameters.put(UnifiedAuthenticationConstants.ParameterName.sign, retrieveSign(parameters, settings.getEncryptionAlgorithm() ));

        return parameters;
    }


    private String retrieveSign(Map<String, Object> parameters, String encryptionAlgorithm) {
        // encryption-algorithm  encryptionAlgorithm
        String sign = null;
        if (StringUtils.isNotBlank(encryptionAlgorithm) && UnifiedAuthenticationConstants.Algorithm.RSA.equals(encryptionAlgorithm)) {
            // RSA 本地签名
            // sign = ZwfwJmasApiSignatureUtils.rsaSign(params, privateKey, ZwfwJmasApiConstants.CHARSET);
        } else {
            String responseBodyString = HttpUtil.post(this.settings.getBaseUrl() + this.settings.getSignPath(),
                    parameters, UnifiedAuthenticationConstants.TIMEOUT);
            sign = parseSign(responseBodyString);
        }
        return sign;
    }

    private String parseSign(String json) {
        // 解析 JSON 字符串为 JSONObject
        JSONObject jsonObject = JSONUtil.parseObj(json);
        // 检查code和success字段
        if ("200".equals(jsonObject.getStr("code")) && jsonObject.getBool("success")) {
            // 获取 data 字段对应的 JSONObject
            JSONObject dataObject = jsonObject.getJSONObject("data");
            if (dataObject != null) {
                // 从 data 中获取 sign 的值
                String sign = dataObject.getStr("sign");
                // System.out.println("sign 的值为: " + sign);
                return sign;
            } else {
                System.out.println("data 字段不存在");
            }
        } else {
            System.out.println("code 不是 200 或者 success 不是 true");
        }
        return null;
    }

    private String descrypt(String cipherText, String privateKey ) {
        ECPrivateKeyParameters privateKeyParams  = null;
        try {
            privateKeyParams = SM2KeyGenerator.generatePrivateKeyParams(privateKey);
        } catch (CommonCryptoException e) {
            throw new RuntimeException(e);
        }
        byte[] decryptedBytes = ByteUtils.hexToBytes(cipherText);
        // decrypt   decryptFromC1C3C2  decryptFromDER
        try {
            return  new String(SM2Cipher.decryptFromC1C3C2(decryptedBytes, privateKeyParams, SM2Cipher.CRYPTO_ALGORITHM_SM2), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        } catch (InvalidCipherTextException e) {
            throw new RuntimeException(e);
        }
    }

    private String getDataJson(String parameterName, String parameterValue) {
        Map<String, String> content = new HashMap<>(1);
        content.put(parameterName, parameterValue);
        BizContentParameter data = new BizContentParameter(this.settings.getApplicationId(), content);

        Map<String, Object> parameters = buildRequestParameters(this.settings, UnifiedAuthenticationConstants.ServiceName.retrieveToken, data);

        String responseBodyString = HttpUtil.post(this.settings.getBaseUrl() + this.settings.getExchangeTokenPath(),
                parameters, UnifiedAuthenticationConstants.TIMEOUT);
        // 解析JSON字符串为JSONObject
        JSONObject jsonObject = JSONUtil.parseObj(responseBodyString);
        // 获取"data"字段的字符串值
        String cipherText = jsonObject.getStr("data");
        String jsonText = descrypt(cipherText, this.settings.getPrivateKey());
        return jsonText;
    }

    /*
    try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
        // HttpGet request = new HttpGet("https://jsonplaceholder.typicode.com/posts/1");
        HttpPost post = new HttpPost("https://jsonplaceholder.typicode.com/posts");
        String json = "{\"title\":\"test\", \"body\":\"example\", \"userId\":1}";
        post.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));
        post.setHeader("Content-Type", "application/json");  // 设置请求头[1,3,5](@ref)

        try (CloseableHttpResponse response = httpClient.execute(post)) {
            System.out.println("Status Code: " + response.getCode());
            System.out.println("Response: " + EntityUtils.toString(response.getEntity()));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    */

    // 其他业务方法...
}